package main

import (
	"Godemo/W1/demo/retriever/fake"
	"Godemo/W1/demo/retriever/real"
	"fmt"
	"time"
)

type Retriever interface {
	Get(url string) string
}

type Poster interface {
	Post(url string,
		form map[string]string) string
}

const url = "https://www.hyperledger.org/"

func download(r Retriever) string {
	return r.Get(url)
}

func post(poster Poster) {
	poster.Post(url,
		map[string]string{
			"name":    "lcl1024",
			"project": "fabric",
		})
}

type RetrieverPoster interface {
	Retriever
	Poster
}

func session(s RetrieverPoster) string {
	s.Post(url, map[string]string{
		"contents": "hyperledger fabric",
	})
	return s.Get(url)
}

func main() {
	var r Retriever
	retriever := fake.Retriever{"this is a fake fabric.com"}
	r = &retriever
	//fmt.Printf("%T %v\n", r, r)
	inspect(r)

	r = &real.Retriever{
		UserAgent: "Chrome",
		TimeOut:   time.Minute,
	}
	//fmt.Printf("%T %v\n", r, r)
	inspect(r)

	// Type assertion
	if realRetriever, ok := r.(*real.Retriever); ok {
		fmt.Println(realRetriever.TimeOut)
	} else {
		fmt.Println("not a real retriever")
	}

	fmt.Println("Try a session")
	fmt.Println(session(&retriever))

}

func inspect(r Retriever) {
	fmt.Printf("%T %v\n", r, r)

	switch v := r.(type) {
	case *fake.Retriever:
		fmt.Println("Contents:", v.Contents)
	case *real.Retriever:
		fmt.Println("UserAgent:", v.UserAgent)
	}
}
